package serie04;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.NavigableMap;
import java.util.NavigableSet;
import java.util.TreeMap;

public class StdPhoneBook implements PhoneBook {
	
	// ATTRIBUTS
	
	private NavigableMap<Contact, List<String>> phoneBook;
	
	// CONSTRUCTEURS
	
	public StdPhoneBook() {
		phoneBook = new TreeMap<Contact, List<String>>();
	}
	
    // REQUETES
    
    public String firstPhoneNumber(Contact p) {
    	if (p == null || !contains(p)) {
    		throw new IllegalArgumentException("Mauvais choix de contact");
    	}
    	return phoneBook.get(p).get(0);
    }
    
    public List<String> phoneNumbers(Contact p) {
    	if (p == null || !contains(p)) {
    		throw new IllegalArgumentException("Mauvais choix de contact");
    	}
    	return Collections.unmodifiableList(phoneBook.get(p));
    }
    
    public NavigableSet<Contact> contacts() {
    	return phoneBook.navigableKeySet();
    }
    
    public boolean contains(Contact p) {
    	if (p == null) {
    		throw new IllegalArgumentException("Ce contact n'existe pas");
    	}
    	return phoneBook.containsKey(p);
    }
    
    public boolean isEmpty() {
    	return contacts().size() == 0;
    }
    
    // COMMANDES
    
    public void addEntry(Contact p, List<String> nums) {
    	if (p == null || contains(p)) {
    		throw new IllegalArgumentException("Mauvais choix de contact");
    	}
    	if (nums == null || nums.size() <= 0) {
    		throw new IllegalArgumentException("Mauvaise liste de numeros");
    	}
    	phoneBook.put(p, new LinkedList<String>(new HashSet<String>(nums)));
    }
    
    public void addPhoneNumber(Contact p, String n) {
    	if (p == null) {
    		throw new IllegalArgumentException("Ce contact n'existe pas");
    	}
    	if (n == null || n.equals("")) {
    		throw new IllegalArgumentException("Mauvais numéro");
    	}
    	if (!contains(p)) {
    		// la personne p n'existe pas on crée une nouvelle entree
    		List<String> lst = new ArrayList<String>();
    		lst.add(n);
    		addEntry(p, lst);
    	} else if (!phoneNumbers(p).contains(n)) {
    		// le numero n n'est pas dans la liste, on l'ajoute
    		phoneBook.get(p).add(n);
    	}
    }
    
    public void removeEntry(Contact p) {
    	if (p == null || !contains(p)) {
    		throw new IllegalArgumentException("Mauvais choix de contact");
    	}
    	phoneBook.remove(p);
    }
    
    public void deletePhoneNumber(Contact p, String n) {
    	if (p == null || !contains(p)) {
    		throw new IllegalArgumentException("Mauvais choix de contact");
    	}
    	if (n == null || n.equals("")) {
    		throw new IllegalArgumentException("Mauvais numéro");
    	}
    	if (phoneNumbers(p).contains(n)) {
    		// Ce contact p possede bien ce numero n dans sa liste de numeros
    		if (phoneNumbers(p).size() == 1) {
    			// Ce contact n'avait qu'un numero : on retire ce contact
    			removeEntry(p);
    		} else {
    			int index = phoneBook.get(p).indexOf(n);
    			phoneBook.get(p).remove(index);
    		}
    	}
    }
    
    public void clear() {
    	phoneBook.clear();
    }
}
